﻿using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using StockUtil;

namespace StockLib.UserData
{
    public class BlockRegularFileLoader
    {
        public virtual void Load()
        {
            FileInfo fi = new FileInfo(StockUserData.Instance.GetFileName(UserDataType.Domain));
            if (!fi.Exists)
                return;

            FileStream fs = null;
            int packSize = 0;
            int packOffset = 0;
            int byteNumber = 0;
            byte[] buffer = null;

            try
            {
                fs = new FileStream(fi.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);

                buffer = new byte[Marshal.SizeOf(typeof(BlockCustomFileHead))];
                byteNumber = fs.Read(buffer, 0, buffer.Length);
                if (byteNumber != buffer.Length)
                    return;

                StockBlockGroupRegular.Instance.Clear();

                BlockCustomFileHead head = (BlockCustomFileHead)StructHelper.FromBytes(buffer, typeof(BlockCustomFileHead));
                buffer = null;

                packSize = Marshal.SizeOf(typeof(BlockCustomFileDomainPack));
                buffer = new byte[packSize * 100];
                packOffset = 0;
                while (packOffset < head.m_wDomainNumber)
                {
                    if (head.m_wDomainNumber - packOffset >= buffer.Length / packSize)
                    {
                        byteNumber = fs.Read(buffer, 0, buffer.Length);
                    }
                    else
                    {
                        byteNumber = fs.Read(buffer, 0, (head.m_wDomainNumber - packOffset) * packSize);
                    }

                    for (int i = 0; i < byteNumber / packSize; i++)
                    {
                        BlockCustomFileDomainPack pack = (BlockCustomFileDomainPack)StructHelper.FromBytes(buffer, i * packSize, typeof(BlockCustomFileDomainPack));
                        StockBlock domain = new StockBlock();
                        BlockCustomFileDomainPack.ToInternal(ref pack, domain);
                        StockBlockGroupRegular.Instance.Add(domain.BlockId, domain);
                    }

                    packOffset += byteNumber / packSize;
                }
                buffer = null;

                packSize = Marshal.SizeOf(typeof(BlockCustomFileStockPack));
                buffer = new byte[packSize * 100];
                foreach(StockBlock domain in StockBlockGroupRegular.Instance.Values)
                {
                    packOffset = 0;
                    while (packOffset < domain.StockNumber)
                    {
                        if (domain.StockNumber - packOffset >= buffer.Length / packSize)
                        {
                            byteNumber = fs.Read(buffer, 0, buffer.Length);
                        }
                        else
                        {
                            byteNumber = fs.Read(buffer, 0, (domain.StockNumber - packOffset) * packSize);
                        }

                        for (int i = 0; i < byteNumber / packSize; i++)
                        {
                            BlockCustomFileStockPack pack = (BlockCustomFileStockPack)StructHelper.FromBytes(buffer, i * packSize, typeof(BlockCustomFileStockPack));
                            string codeKey = BlockCustomFileStockPack.GetCodeKey(ref pack);
                            if (StockContainer.Instance.ContainsKey(codeKey) && !domain.ContainsKey(codeKey))
                            {
                                domain.Add(codeKey, StockContainer.Instance[codeKey]);
                            }
                        }

                        packOffset += byteNumber / packSize;
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.ToString());
                throw ex;
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                    fs.Dispose();
                }
            }
        }
    }
}
